package plgwsmsg

import (
	"dgo/goutils/utils"
	"fmt"
	"gitee.com/ymofen/supervalue"
	"golang.org/x/net/websocket"
	"strings"
)

const (
	WS_HTTP_CHANNEL_CMD     string = "/cmd"
	WS_TOPIC_KEY            string = "__topic"
	WS_TOKEN_KEY            string = "__token"
	WS_HTTP_CMD_subscribe          = "subscribe"
	WS_HTTP_CMD_unsubscribe        = "unsubscribe"
	WS_MSG_KEY                     = "__msg"

	WS_HTTP_CHANNEL_EVENT_ONCONNECTED string = "/onconnected"
)

func NewJsonMsgServ(sessionPrefix string) *WsMsgServ {
	rval := NewWsMsgServ(sessionPrefix)
	rval.wsMsgType = websocket.BinaryFrame
	rval.handleRecvFunc = func(conn *WsClientConn, buf []byte) {
		json, err := wrapper.NewSVFrom(buf, false)
		if err != nil {
			conn.reqDis(fmt.Sprintf("[err]:非法的消息(JSON):%s", err.Error()))
			return
		}

		topic := json.StringByName(WS_TOPIC_KEY, "")
		if topic == WS_HTTP_CHANNEL_CMD {
			cmd := json.StringByName("cmd", "")
			token := json.StringByName(WS_TOKEN_KEY, "")
			if cmd == WS_HTTP_CMD_subscribe {
				str := json.StringByName("channels", "")
				cnt := 0
				if len(str) > 0 {
					strs := strings.Split(str, ",")
					for i := 0; i < len(strs); i++ {
						conn.SubFunc(utils.Trim(strs[i]))
						cnt++
					}
				}
				conn.SendMsgFunc(utils.BuildJSONBytes("code", 0, WS_TOKEN_KEY, token, "cmd", cmd, "channels", str, "n", cnt, "client-addr", conn.RemoteAddr))
			} else if cmd == WS_HTTP_CMD_unsubscribe {
				str := json.StringByName("channels", "")
				cnt := 0
				if len(str) > 0 {
					strs := strings.Split(str, ",")
					for i := 0; i < len(strs); i++ {
						topicstr := utils.Trim(strs[i])
						if len(topicstr) > 0 && conn.subchannels[topicstr] == struct{}{} {
							conn.UnsubFunc(topicstr)
							cnt++
						}
					}
				}
				conn.SendMsgFunc(utils.BuildJSONBytes("code", 0, WS_TOKEN_KEY, token, "cmd", cmd, "channels", str, "n", cnt, "client-addr", conn.RemoteAddr))
			}
		} else if topic == "__ECHO" {
			conn.SendMsgFunc(buf)
		} else {
			token := json.StringByName(WS_TOKEN_KEY, "")
			json.RemoveKey(WS_TOKEN_KEY)
			cnt := rval.ex.Pub(topic, 0, json.AsJSONString(false))
			conn.SendMsgFunc(utils.BuildJSONBytes("code", 0, WS_TOKEN_KEY, token, "topic", topic, "n", cnt))
		}
	}
	return rval
}
